/*
 * FileName：WebMvcConfg.java 
 * <p>
 * Copyright (c) 2017-2020 <a href="">hermit(1154808491@qq.com)</a>.
 * <p>
 * Licensed under the GNU General Public License, Version 3 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.gnu.org/licenses/gpl-3.0.html
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 */
package com.koine.admin.config;

import com.koine.common.util.PropertiesUtil;
import com.koine.admin.interceptor.AuthInterceptor;
import com.koine.admin.interceptor.LogInterceptor;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.Ordered;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.*;

import javax.servlet.MultipartConfigElement;
import java.util.ArrayList;
import java.util.List;

@Configuration
public class WebMvcConfg implements WebMvcConfigurer {

    /**
     * 本地文件路径
     */
    public static final String localFilePath="file:%s";
    /**
     * 增加corsfilter防止顺序作乱
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean<CorsFilter> corsFilter() {
        UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
        CorsConfiguration config = new CorsConfiguration();
        config.setAllowCredentials(true);
        config.addAllowedOrigin("*");
        config.addAllowedHeader("*");
        config.addAllowedMethod("*");
        source.registerCorsConfiguration("/**", config);
        FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
        bean.setOrder(0);
        return bean;
    }

    /**
     * 增加utf-8乱码
     *
     * @return
     */
    @Bean
    public FilterRegistrationBean<CharacterEncodingFilter> encodingFilterRegistration() {
        CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding("UTF-8");
        encodingFilter.setForceEncoding(true);
        FilterRegistrationBean<CharacterEncodingFilter> registration = new FilterRegistrationBean<CharacterEncodingFilter>(
                encodingFilter);
        registration.setName("encodingFilter");
        registration.addUrlPatterns("/*");
        registration.setAsyncSupported(true);
        registration.setOrder(1);
        return registration;
    }

    /**
     * 定制URL匹配规则 （后缀模式匹配、自动后缀路径模式匹配）
     *
     * @param configurer
     */
    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        configurer.setUseSuffixPatternMatch(true).
                setUseTrailingSlashMatch(true);
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加登陆拦截器
        List<String> patterns = new ArrayList<>();
        patterns.add("/wxapi/**");
        patterns.add("/temporary/**");
        patterns.add("/upload/**");
        patterns.add("/managerImg/**");
        patterns.add("/css/**");
        patterns.add("/font/**");
        patterns.add("/images/**");
        patterns.add("/js/**");
        patterns.add("/views/**");
        patterns.add("/message/**");
        patterns.add("/front/**");
        patterns.add("/user/**");
        patterns.add("/swagger-resources/**");
        patterns.add("/v2/**");
        patterns.add("/swagger-ui.html");
        patterns.add("/swagger-ui.html/**");
        patterns.add("/webjars/**");
        String[] allowUrls = {"/", "/common/getverifycode","/managerImg/ueditor"};
        AuthInterceptor authInterceptor = new AuthInterceptor();
        authInterceptor.setAllowUrls(allowUrls);
        registry.addInterceptor(authInterceptor)
                .addPathPatterns("/**")
                .excludePathPatterns(patterns);
//        添加log拦截器
        LogInterceptor logInterceptor = new LogInterceptor();
        registry.addInterceptor(logInterceptor).excludePathPatterns(patterns);
        //添加oauth拦截器
//        WxOAuth2Interceptor wxOAuth2Interceptor = new WxOAuth2Interceptor();
//        registry.addInterceptor(wxOAuth2Interceptor).addPathPatterns(Arrays.asList("/front/voteindex/getVoteIndex", "/front/voteindex/getVoteApplyIndex",
//                "/front/voteindex/getVoteIndex", "front/voteindex/getVoteApplyIndex", "/front/mobile"));
    }

    //配置首页启动
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/").setViewName("forward:/views/login.html");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }

    /**
     * 允许跨域访问
     *
     * @param registry
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("POST", "GET", "PUT", "OPTIONS", "DELETE")
                .maxAge(3600)
                .allowCredentials(true);
    }

    /**
     * 文件上传配置
     */
    @Bean
    public MultipartConfigElement multipartConfigElement() {
        MultipartConfigFactory factory = new MultipartConfigFactory();
        // 文件最大
        factory.setMaxFileSize("1024Mb"); // KB,MB
        /// 设置总上传数据总大小
        factory.setMaxRequestSize("1024Mb");
        return factory.createMultipartConfig();
    }

    // 资源重定向
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/upload/**").addResourceLocations("classpath:/upload/");
        registry.addResourceHandler("/temporary/**").addResourceLocations(String.format(localFilePath,PropertiesUtil.getString("res.upload.path")));
        registry.addResourceHandler("/**").addResourceLocations("/WEB-INF/", "classpath:/META-INF/resources/",
                "classpath:/resources/", "classpath:/static/", "classpath:/public/", "classpath:/views/");
    }
}
